#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/keysymdef.h>
#include <tinywidgets/tnWidgets.h>
#include "util.h"
#include "global.h"
#include "intfMsg.h"

#define MEDIA_DATA_PATH  "/mnt/data/ext/media"

extern int ir_main(int msqid);
static int process_key_handler(uint32_t key);

static int msqid_myplayer;
static int msqid_bsqplayer;
static int _volume = -10;

static const char * _file_playing = NULL;

static const char * next_file_fullpath(int skip)
{
    static char _f_return[1024];
    const char * f = next_file(skip);
    sprintf(_f_return, "%s/%s", MEDIA_DATA_PATH, f);
    return _f_return;
}

static void player_file(const char * f)
{
    RtnMsg m, *msg = &m;
    sprintf(msg->msg_data, "U %s", f);
    msg->msg_len = strlen(msg->msg_data) + 1;
    msg->msg_code = 0;
    loge("%s\n", msg->msg_data);
    SendMessage(msqid_bsqplayer, msg);
}

static void player_stop()
{
    RtnMsg m, *msg = &m;
    strcpy(msg->msg_data, "s");
    msg->msg_len = strlen(msg->msg_data) + 1;
    msg->msg_code = 0;
    SendMessage(msqid_bsqplayer, msg);
}

static void player_pause()
{
    RtnMsg m, *msg = &m;
    strcpy(msg->msg_data, " ");
    msg->msg_len = strlen(msg->msg_data) + 1;
    msg->msg_code = 0;
    SendMessage(msqid_bsqplayer, msg);
    logd("paused\n");
}

static void player_resume()
{
    RtnMsg m, *msg = &m;
    strcpy(msg->msg_data, "r");
    msg->msg_len = strlen(msg->msg_data) + 1;
    msg->msg_code = 0;
    SendMessage(msqid_bsqplayer, msg);
    logd("resumed\n");
}

static void player_volume(int v)
{
    RtnMsg m, *msg = &m;
    sprintf(msg->msg_data, "v %d", v);
    msg->msg_len = strlen(msg->msg_data) + 1;
    msg->msg_code = 0;
    SendMessage(msqid_bsqplayer, msg);
}

int main(int argc, char ** argv)
{
    msqid_myplayer      = OpenMsgQueue(KEY_FOR_PLAYER_MESSAGE);
    msqid_bsqplayer     = OpenMsgQueue(KEY_FOR_BSQPLAYER_MESSAGE);

    // ir
    if (fork() == 0) {
        ir_main(msqid_myplayer);
        exit(0);
    }

    // init file list
    if (init_list_path(MEDIA_DATA_PATH) <= 0) {
        loge("no files in '%s'\n", MEDIA_DATA_PATH);
        exit(-1);
    }

    _file_playing = next_file_fullpath(1);
    player_file(_file_playing);
    player_volume(_volume);

    // message process
    RtnMsg msg;
    while (GetMessage(msqid_myplayer, &msg) == 0) {
        switch (msg.msg_code) {
            case MSG_MAIN_IR_KEYCODE:
                {
                    uint32_t key;
                    memcpy(&key, msg.msg_data, sizeof(key));
                    process_key_handler(key);
                    break;
                }
            case MSG_PLAYER_ENDFILE:
                player_file( next_file_fullpath(1) );
                break;
            case MSG_PLAYER_FILE_ERROR:
                loge("player erro\n");
                player_file( next_file_fullpath(1) );
                break;
            default:
                break;
        }
    }

    return 0;
}

static int process_key_handler(uint32_t key)
{
    logd("press key: %x\n", key);
    switch (key) {
        case XK_0:
        case XK_1:
        case XK_2:
        case XK_3:
        case XK_4:
        case XK_5:
        case XK_6:
        case XK_7:
        case XK_8:
        case XK_9:
            player_file( next_file_fullpath(key - XK_0) );
            break;
        case XK_Prior:
        case XK_Left:
            player_file( next_file_fullpath(-1) );
            break;
        case XK_Next:
        case XK_Right:
            player_file( next_file_fullpath(1) );
            break;
        case XK_End:
            rewind_all();
            player_stop();
            break;
        case XK_Pause:
            {
                static int _paused = 0;
                if (!_paused) 
                    player_pause();
                else 
                    player_resume();
                _paused = !_paused;
                break;
            }
        case XK_AudioLowerVolume:
            player_volume(--_volume);
            break;
        case XK_AudioRaiseVolume:
            player_volume(++_volume);
            break;
        default:
            break;
    }
    return 0;
}

